package com.atguigu.dga.lineage.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.atguigu.dga.lineage.bean.GovernanceLineageTable;
import com.atguigu.dga.lineage.service.GovernanceLineageTableService;
import com.atguigu.dga.meta.bean.TableMetaInfo;
import com.atguigu.dga.meta.service.TableMetaInfoService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author zhangchen
 * @since 2024-08-03
 */
@RestController
@RequestMapping("/lineage")
public class GovernanceLineageTableController {

    @Autowired
    GovernanceLineageTableService governanceLineageTableService;

    @Autowired
    TableMetaInfoService tableMetaInfoService;

    @GetMapping("/root/{tableName}")
    public String getRoot(@PathVariable("tableName") String tableName){
        QueryWrapper<GovernanceLineageTable> queryWrapper = new QueryWrapper<GovernanceLineageTable>().like("concat(schema_name,'.',table_name) ", tableName)
                .inSql("governance_date","select max(governance_date) from governance_lineage_table");
        List<GovernanceLineageTable> governanceLineageTableList = governanceLineageTableService.list(queryWrapper);
        GovernanceLineageTable governanceLineageTable = governanceLineageTableList.get(0);


        QueryWrapper<TableMetaInfo> metaQueryWrapper = new QueryWrapper<TableMetaInfo>().inSql("assess_date","select max(assess_date) from table_meta_info");

        List<TableMetaInfo> tableMetaInfoList = tableMetaInfoService.list(metaQueryWrapper);
        Map<String ,String> tableCommentMap=new HashMap();
        for (TableMetaInfo tableMetaInfo : tableMetaInfoList) {

            tableCommentMap.put(tableMetaInfo.getSchemaName()+"."+tableMetaInfo.getTableName(),tableMetaInfo.getTableComment()==null?"":tableMetaInfo.getTableComment());
        }

        // 根节点
        JSONObject rootJsonObj = new JSONObject();
        rootJsonObj.put("isRoot",true);
        rootJsonObj.put("id",governanceLineageTable.getSchemaName()+"."+governanceLineageTable.getTableName());
        rootJsonObj.put("comment",tableCommentMap.get(governanceLineageTable.getSchemaName()+"."+governanceLineageTable.getTableName()));

        //子节点
        List<JSONObject> childrenJsonObjList=new ArrayList<>();
        //来源子节点
        String sourceTables = governanceLineageTable.getSourceTables();
        String[] sourceTableArr = sourceTables.split(",");
        for (String sourceTableName : sourceTableArr) {
            String tableComment = tableCommentMap.get(sourceTableName);
            JSONObject childJsonObj = new JSONObject();
            childJsonObj.put("comment",tableComment);
            childJsonObj.put("id",sourceTableName);
            childJsonObj.put("relation","source");
            childrenJsonObjList.add(childJsonObj);
        }
        //输出子节点
        String sinkTables = governanceLineageTable.getSinkTables();
        String[] sinkTableArr = sinkTables.split(",");
        for (String sinkTableName : sinkTableArr) {
            String tableComment = tableCommentMap.get(sinkTableName);
            JSONObject childJsonObj = new JSONObject();
            childJsonObj.put("comment",tableComment);
            childJsonObj.put("id",sinkTableName);
            childJsonObj.put("relation","sink");
            childrenJsonObjList.add(childJsonObj);
        }

        rootJsonObj.put("children",childrenJsonObjList);

        return rootJsonObj.toJSONString();
    }

    @GetMapping("/child/{tableName}")
    public  String getChild(@PathVariable("tableName") String tableName, @RequestParam("relation") String relation){
        QueryWrapper<GovernanceLineageTable> queryWrapper = new QueryWrapper<GovernanceLineageTable>().inSql("governance_date", "select max(governance_date) from governance_lineage_table")
                .eq("concat(schema_name,'.',table_name)", tableName);
        GovernanceLineageTable governanceLineageTable = governanceLineageTableService.getOne(queryWrapper);

        //查询元数据map 用于翻译表名中文
        QueryWrapper<TableMetaInfo> metaQueryWrapper = new QueryWrapper<TableMetaInfo>().inSql("assess_date","select max(assess_date) from table_meta_info");

        List<TableMetaInfo> tableMetaInfoList = tableMetaInfoService.list(metaQueryWrapper);
        Map<String ,String> tableCommentMap=new HashMap();
        for (TableMetaInfo tableMetaInfo : tableMetaInfoList) {

            tableCommentMap.put(tableMetaInfo.getSchemaName()+"."+tableMetaInfo.getTableName(),tableMetaInfo.getTableComment()==null?"":tableMetaInfo.getTableComment());
        }
        //子节点
        List<JSONObject> childrenJsonObjList=new ArrayList<>();
        if(relation.equals("source")){//来源
            String sourceTables = governanceLineageTable.getSourceTables();
            if(sourceTables!=null&&sourceTables.length()>0){
                String[] sourceTableArr = sourceTables.split(",");
                for (String sourceTableName : sourceTableArr) {
                    String tableComment = tableCommentMap.get(sourceTableName);
                    JSONObject childJsonObj = new JSONObject();
                    childJsonObj.put("comment",tableComment);
                    childJsonObj.put("id",sourceTableName);
                    childJsonObj.put("relation","source");
                    childrenJsonObjList.add(childJsonObj);
                }
            }
        }else{ //输出
            String sinkTables = governanceLineageTable.getSinkTables();
            if(sinkTables!=null&&sinkTables.length()>0) {
                String[] sinkTableArr = sinkTables.split(",");
                for (String sinkTableName : sinkTableArr) {
                    String tableComment = tableCommentMap.get(sinkTableName);
                    JSONObject childJsonObj = new JSONObject();
                    childJsonObj.put("comment", tableComment);
                    childJsonObj.put("id", sinkTableName);
                    childJsonObj.put("relation", "sink");
                    childrenJsonObjList.add(childJsonObj);
                }
            }
        }

        return  JSON.toJSONString(childrenJsonObjList) ;
    }

}
